package net.molchat.binroot;


import java.io.IOException;
import java.io.InputStream;


public class RootReader {

//==================================================================== Constants

//======================================================================= Fields
private InputStream stream;


//================================================================= Constructors
public RootReader(InputStream stream) {

	this.stream = stream;
}


//==================================================================== readBytes
/**
 * Reads byte array.
 */
private byte[] readBytes(int len) throws IOException {

	if (len == 0) {
		System.out.println("Len = 0!");
	}

	// TODO Optimize this method
	byte[] bytes = new byte[len];
	for (int q = 0; q < len; ++q) {
		bytes[q] = (byte) stream.read();
	}

	return bytes;
}


//===================================================================== readRoot
public Root readRoot() throws IOException {


	return readRoot(null, 0);
}


private Root readRoot(Root lastRoot, int deep) throws IOException {

	int header = readVInt();
	boolean fLast = (header & RootWriter.FLAG_LAST) == 0 ? false : true;
	boolean fHasChildren = (header & RootWriter.FLAG_CHILD) == 0 ? false : true;

	// Fill current root
	Root toFill = new Root();
	toFill.nodeId = header >> RootWriter.FLAGS_NUM;
	int len = readVInt();
	if (len > 0) {
		toFill.data = readBytes(len);
	}

	// Fill the internal structure if needed
	if (fHasChildren) {
		readRoot(toFill, ++deep);
		deep--;
	}

	if (lastRoot != null) {
		lastRoot.addChild(toFill);
	}

	if (!fLast) {
		readRoot(lastRoot, deep);
	}


	return toFill;
}


//===================================================================== readVInt
/**
 * Reads variable length unsigned int. Little-endian.
 * 
 */
private int readVInt() throws IOException {

	int byt; // Прочитанный байт
	int ret = 0; // Возвращаемая величина
	int offset = 0; // Смещение

	do {
		byt = stream.read();
		ret += (byt & 0x7f) << offset;
		offset += 7;
	} while ((byt & 0x80) != 0);

	return ret;
}


}
